import Singleton from "../base/Singleton";
import { EVENT_NAME_ENUM } from "../base/EnumIndex";
interface iItem {
    func: Function,
    ctx: unknown
}
export class EventManager extends Singleton {
    static get ins() {
        return super.getInstance<EventManager>();
    }

    private eventDic: Map<string, Array<iItem>> = new Map();

    on(eventName: EVENT_NAME_ENUM, func: Function, ctx?: unknown) {
        if (this.eventDic.has(eventName)) {
            this.eventDic.get(eventName).push({ func, ctx });
        } else {
            this.eventDic.set(eventName, [{ func, ctx }]);
        }
    }
    off(eventName: EVENT_NAME_ENUM, func: Function, ctx?: unknown) {
        if (this.eventDic.has(eventName)) {
            const index = this.eventDic.get(eventName).findIndex(i => i.func === func && i.ctx === ctx);
            index > -1 && this.eventDic.get(eventName).splice(index, 1);
        }
    }
    emit(eventName: EVENT_NAME_ENUM, ...params: unknown[]) {
        let result = undefined;
        if (this.eventDic.has(eventName)) {
            this.eventDic.get(eventName).forEach(({ func, ctx }) => {
                result = ctx ? func.apply(ctx, params) : func(...params)
                // result = ctx ? func.call(ctx, ...params) : func(...params)
            });
        }
        return result;
    }
    offAll(ctx: unknown) {
        for (const key in this.eventDic) {
            let arr = this.eventDic.get(key);
            for (let i = arr.length - 1; i >= 0; i--) {
                if (arr[i].ctx === ctx) {
                    arr.splice(i, 1);
                }
            }
        }
    }
    clear() {
        this.eventDic.clear();
    }
}
